import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class MPEssMiner extends Script implements PaintListener {

	int failCount = 0;

	int loads = 0;

	boolean cameraMoving = false;

	boolean clickedRock = false;

	boolean spinningView = false;

	boolean walkingToBankBooth = false;

	boolean usingPortal = false;

	boolean walkingToPortal = false;

	boolean teleporting = false;

	public RSTile bankTile = new RSTile(3253, 3421);

	public RSTile shopTile = new RSTile(3253, 3401);

	public RSTile centerTile = new RSTile(2910, 4832);

	public RSTile nwPortalTile = new RSTile(2886, 4850);

	public RSTile swPortalTile = new RSTile(2890, 4813);

	public RSTile sePortalTile = new RSTile(2932, 4815);

	public RSTile nePortalTile = new RSTile(2931, 4854);

	/*
	 * 
	 * boolean attacked = false;
	 * 
	 * int attHP = -1;
	 * 
	 * public boolean checkAttack() { int maxHP =
	 * skills.getLvlByExp(skills.getCurrentSkillExp(3)); int curHP =
	 * skills.getCurrentSkillLevel(3); if(curHP < maxHP) { if(attacked) {
	 * if(curHP > attHP) { attHP = curHP; } if(curHP >= attHP) { return false; }
	 * else { attacked = false; } } if(!attacked) { if(inMine()) { usePortal();
	 * } else if(atBank()) { bankToShop(); } attHP = -1; attacked = true; return
	 * true; } } else { if(attacked) { attacked = false; } if(attHP != -1) {
	 * attHP = -1; } } return false; }
	 */

	public RSTile bankBoothTile = new RSTile(3253, 3420);

	public RSTile neRockTile = new RSTile(2927, 4849);

	public RSTile neByRockTile = new RSTile(2925, 4847);

	public RSTile nwRockTile = new RSTile(2893, 4848);

	public RSTile nwByRockTile = new RSTile(2895, 4846);

	public RSTile seRockTile = new RSTile(2927, 4816);

	public RSTile seByRockTile = new RSTile(2926, 4816);

	public RSTile swRockTile = new RSTile(2895, 4813);

	public RSTile swByRockTile = new RSTile(2897, 4811);

	public int bankBoothID = 11402;

	public int rockID = 2491;

	/*
	 * public boolean checkLost() { if(!inCave() && distanceTo(bankTile) > 15 &&
	 * distanceTo(shopTile) > 20) { homeTele(); return true; } return false; }
	 */

	public int portalID = 2492;

	public int closedDoorID = 24381;

	public RSTile[] bankToShopPath = { new RSTile(3254, 3426),
			new RSTile(3260, 3416), new RSTile(3260, 3405),
			new RSTile(3253, 3399) };

	public RSTile[] shopToBankPath = { new RSTile(3253, 3398),
			new RSTile(3256, 3409), new RSTile(3260, 3420),
			new RSTile(3254, 3428) };

	public RSTile[] centerToMinePath = { new RSTile(2906, 4827),
			new RSTile(2901, 4817), new RSTile(2897, 4811) };

	public RSTile[] walkBackPath = { new RSTile(3222, 3219),
			new RSTile(3233, 3221), new RSTile(3244, 3225),
			new RSTile(3255, 3227), new RSTile(3259, 3238),
			new RSTile(3257, 3249), new RSTile(3252, 3259),
			new RSTile(3247, 3269), new RSTile(3241, 3279),
			new RSTile(3239, 3290), new RSTile(3239, 3301),
			new RSTile(3244, 3311), new RSTile(3251, 3320),
			new RSTile(3262, 3322), new RSTile(3270, 3330),
			new RSTile(3281, 3332), new RSTile(3286, 3342),
			new RSTile(3295, 3349), new RSTile(3299, 3360),
			new RSTile(3299, 3371), new RSTile(3296, 3382),
			new RSTile(3294, 3393), new RSTile(3293, 3404),
			new RSTile(3292, 3415), new RSTile(3283, 3422),
			new RSTile(3272, 3426), new RSTile(3261, 3427),
			new RSTile(3253, 3421) };

	public boolean atBank() {
		return distanceTo(bankTile) < 12;
	}

	public boolean atShop() {
		return distanceTo(shopTile) < 5;
	}

	public boolean bankToShop() {
		return dpWalkPath(bankToShopPath);
	}

	public boolean centerToMine() {
		return dpWalkPath(centerToMinePath);
	}

	public boolean checkAttack() {
		if (getMyPlayer().isInCombat()) {
			if (inMine()) {
				usePortal();
				return true;
			} else if (atBank()) {
				bankToShop();
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	public boolean checkCamera() {
		if (cameraMoving) {
			if (Bot.getClient().getCameraCurveY() >= 380) {
				Bot.getInputManager().releaseKey((char) KeyEvent.VK_UP);
				cameraMoving = false;
			}
			return true;
		} else if (Bot.getClient().getCameraCurveY() < 380) {
			Bot.getInputManager().pressKey((char) KeyEvent.VK_UP);
			cameraMoving = true;
			return true;
		}
		return false;
	}

	public boolean checkClickedRock() {
		if (clickedRock) {
			clickedRock = false;
			return true;
		}
		return false;
	}

	public boolean checkSpinningView() {
		if (spinningView) {
			Bot.getInputManager().releaseKey((char) KeyEvent.VK_RIGHT);
			spinningView = false;
			return true;
		} else {
			return false;
		}
	}

	public boolean checkTeleporting() {
		if (teleporting) {
			teleporting = false;
			return true;
		}
		return false;
	}

	public boolean checkUsingPortal() {
		if (usingPortal) {
			usingPortal = false;
			return true;
		} else {
			return false;
		}
	}

	public boolean checkWalkingToBankBooth() {
		if (walkingToBankBooth) {
			walkingToBankBooth = false;
			return true;
		} else {
			return false;
		}
	}

	public boolean checkWalkingToPortal() {
		if (walkingToPortal) {
			walkingToPortal = false;
			return true;
		} else {
			return false;
		}
	}

	public boolean clickNERockTile() {
		return dpClickRockTile(neRockTile);
	}

	public boolean clickNWRockTile() {
		return dpClickRockTile(nwRockTile);
	}

	public boolean clickRock() {
		if (inNEMine()) {
			return clickNERockTile();
		}
		if (inNWMine()) {
			return clickNWRockTile();
		}
		if (inSEMine()) {
			return clickSERockTile();
		}
		if (inSWMine()) {
			return clickSWRockTile();
		}
		return false;
	}

	public boolean clickSERockTile() {
		return dpClickRockTile(seRockTile);
	}

	public boolean clickSWRockTile() {
		return dpClickRockTile(swRockTile);
	}

	public int distanceToByRockTile() {
		if (inNEMine()) {
			return distanceTo(neByRockTile);
		}
		if (inSEMine()) {
			return distanceTo(seByRockTile);
		}
		if (inNWMine()) {
			return distanceTo(nwByRockTile);
		}
		if (inSWMine()) {
			return distanceTo(swByRockTile);
		}
		return -1;
	}

	public int doBank() {
		if (inCave()) {
			if (inMine()) {
				setRun(true);
				if (usePortal()) {
					return random(700, 900);
				} else {
					if (walkToRock()) {
						return random(500, 800);
					} else {
						log("E-4");
						return -1;
					}
				}
			} else {
				if (centerToMine()) {
					return random(500, 800);
				} else {
					log("E-5");
					return -1;
				}
			}
		} else {
			if (atBank()) {
				if (RSInterface.getInterface(Constants.INTERFACE_BANK)
						.isValid()) {
					bank.depositAllExcept(1275, 1265, 1269, 1267, 1273, 1271);
					loads++;
					return random(1000, 2000);
				} else {
					if (distanceTo(bankBoothTile) > 1) {
						if (walkToBankBooth()) {
							return random(500, 800);
						} else {
							return -1;
						}
					}
					final RSObject object = findObject(bankBoothID);
					if (atObject(object, "uickly")) {
						return random(500, 800);
					} else {
						if (walkToBankBooth()) {
							return random(500, 800);
						} else {
							log("E-6");
							return -1;
						}
					}
				}
			} else {
				if (walkToBankBooth()) {
					return random(500, 800);
				} else {
					if (shopToBank()) {
						return random(500, 800);
					} else {
						log("E-7");
						return -1;
					}
				}
			}
		}
	}

	public int doMine() {
		if (inCave()) {
			if (inMine()) {
				clickedRock = clickRock();
				if (clickedRock) {
					return random(500, 800);
				} else {
					final int result = distanceToByRockTile();
					if (result == -1) {
						return -1;
					}
					if (result > 0) {
						if (walkToRock()) {
							return random(500, 800);
						} else {
							log("E-1");
							return -1;
						}
					} else {
						spinView();
						return random(500, 800);
					}
				}
			} else {
				if (centerToMine()) {
					return random(500, 800);
				} else {
					log("E-2");
					return -1;
				}
			}
		} else {
			if (atShop()) {
				if (openDoor()) {
					return random(500, 800);
				}
				if (teleportToCave()) {
					return random(500, 800);
				} else {
					if (walkIntoShop()) {
						return random(500, 800);
					} else {
						log("E-3");
						if (atShop()) {
							log("atshop true");
						} else {
							log("atshop false");
						}
						return -1;
					}
				}
			} else {
				if (bankToShop()) {
					return random(500, 800);
				} else {
					log("E-8");
					return -1;
				}
			}
		}
	}

	public boolean dpClickRockTile(final RSTile tile) {
		/*
		 * if (Calculations.tileToScreen(tile).getX() == -1) { return false; }
		 * Point point = new Point((int) Calculations.tileToScreen(tile).getX()
		 * + random(-2,2), (int) Calculations.tileToScreen(tile).getY() +
		 * random(-2, 2)); moveMouse(point); clickMouse(point, true); return
		 * true;
		 */
		return atTile(tile, "ine");
	}

	public boolean dpWalkPath(final RSTile[] path) {
		for (int i = path.length - 1; i >= 0; i--) {
			if (dpWalkTile(path[i])) {
				return true;
			}
		}
		return false;
	}

	public boolean dpWalkTile(final RSTile tile) {
		if (distanceTo(tile) <= 16) {
			walkTileMM(tile);
			return true;
		} else {
			return false;
		}
	}

	@Override
	public String getAuthor() {
		return "MrPanda/DontPanic";
	}

	@Override
	public String getName() {
		return "MrPanda's Ess Miner";
	}

	@Override
	public String getScriptCategory() {
		return "Mining";
	}

	@Override
	public String getScriptDescription() {
		String html = "";

		html += "<html>\n";
		html += "<body>\n";
		html += "<h2>" + getName() + " v" + getVersion() + "</h2><br>\n";
		html += "Author: " + getAuthor() + "<br><br>\n";
		html += "Start anywhere with pickaxe in inventory or equipped.";
		// html += "<center>\n";
		// html += "Arguments:<input type=\"text\" name=\"args\">\n";
		// html += "</center>\n";
		html += "</body>\n";
		html += "</html\n";

		return html;
	}

	@Override
	public double getVersion() {
		return 1.1;
	}

	public void homeTele() {
		openTab(Constants.TAB_MAGIC);
		castSpell(1);
	}

	public boolean inCave() {
		return distanceTo(centerTile) < 50;
	}

	public boolean inCenter() {
		return distanceTo(centerTile) < 10;
	}

	public boolean inMine() {
		return inCave() && !inCenter();
	}

	public boolean inMineTile(final RSTile tile) {
		return distanceTo(tile) < 15;
	}

	public boolean inNEMine() {
		return inMineTile(neRockTile);
	}

	public boolean inNWMine() {
		return inMineTile(nwRockTile);
	}

	public boolean inSEMine() {
		return inMineTile(seRockTile);
	}

	public boolean inSWMine() {
		return inMineTile(swRockTile);
	}

	@Override
	public int loop() {
		if (!isLoggedIn()) {
			return random(100, 200);
		}
		if (checkSpinningView()) {
			return random(200, 300);
		}
		if (checkCamera()) {
			return random(500, 800);
		}
		if (getMyPlayer().isMoving()) {
			return random(150, 200);
		}
		if (checkTeleporting()) {
			return random(2800, 2900);
		}
		if (checkWalkingToBankBooth()) {
			return random(500, 600);
		}
		if (checkUsingPortal()) {
			return random(300, 400);
		}
		if (checkClickedRock()) {
			return random(800, 1000);
		}
		if (checkWalkingToPortal()) {
			return random(300, 350);
		}
		if (checkAttack()) {
			return random(800, 1000);
		}
		if (getMyPlayer().getAnimation() != -1) {
			return random(3000, 5000);
		}
		int result;
		if (getInventoryCount() != 28) {
			result = doMine();
		} else {
			result = doBank();
		}
		if (result != -1) {
			failCount = 0;
			return result;
		}
		log("walkBack");
		if (walkBack()) {
			failCount = 0;
			return random(500, 800);
		}
		failCount++;
		if (failCount >= 10) {
			log("homeTele");
			failCount = 0;
			homeTele();
			return random(2000, 3000);
		}
		return random(1000, 2000);
		/*
		 * log("checkLost"); if(checkLost()) { return random(2000, 3000); }
		 * return random(100, 200);
		 */
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public void onRepaint(final Graphics g) {
		g.setColor(Color.GREEN);
		g.drawString("MrPanda's/DontPanic's Ess Miner", 260, 20);
		g.drawString("Loads: " + loads, 260, 38);
	}

	@Override
	public boolean onStart(final String[] args) {
		bankToShopPath = randomizePath(bankToShopPath, 2, 2);
		shopToBankPath = randomizePath(shopToBankPath, 2, 2);
		centerToMinePath = randomizePath(centerToMinePath, 2, 2);
		walkBackPath = randomizePath(walkBackPath, 2, 2);
		return true;
	}

	public boolean openDoor() {
		final RSObject object = findObject(24381);
		if (object == null || object.getLocation().getX() != 3253) {
			return false;
		}
		final Point point = new Point((int) Calculations.tileToScreen(
				object.getLocation()).getX(), (int) Calculations.tileToScreen(
				object.getLocation()).getY()
				- random(18, 20));
		moveMouse(point);
		clickMouse(point, true);
		return true;
	}

	public boolean shopToBank() {
		if (openDoor()) {
			return true;
		}
		return dpWalkPath(shopToBankPath);
	}

	public void spinView() {
		Bot.getInputManager().pressKey((char) KeyEvent.VK_RIGHT);
		spinningView = true;
	}

	public boolean teleportToCave() {
		final RSNPC npc = getNearestFreeNPCByName("Aubury");
		if (atNPC(npc, "eleport")) {
			teleporting = true;
			return true;
		} else {
			return false;
		}
	}

	public boolean usePortal() {
		final RSObject object = findObject(portalID);
		if (atObject(object, "Use")) {
			usingPortal = true;
			return true;
		} else {
			if (dpWalkTile(nePortalTile)) {
			} else if (dpWalkTile(nwPortalTile)) {
			} else if (dpWalkTile(sePortalTile)) {
			} else if (dpWalkTile(swPortalTile)) {
			} else {
				return false;
			}
			walkingToPortal = true;
			return true;
		}
	}

	public boolean walkBack() {
		return dpWalkPath(walkBackPath);
	}

	public boolean walkIntoShop() {
		return dpWalkTile(shopTile);
	}

	public boolean walkToBankBooth() {
		if (dpWalkTile(bankBoothTile)) {
			walkingToBankBooth = true;
			return true;
		} else {
			return false;
		}
	}

	public boolean walkToRock() {
		if (dpWalkTile(neByRockTile)) {
			return true;
		} else if (dpWalkTile(nwByRockTile)) {
			return true;
		} else if (dpWalkTile(seByRockTile)) {
			return true;
		} else if (dpWalkTile(swByRockTile)) {
			return true;
		} else {
			return false;
		}
	}

}